package com.xingzhengfan.eurekaclient;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractJsonMessageConverter;
import org.springframework.amqp.support.converter.DefaultJackson2JavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JavaTypeMapper;
import org.springframework.amqp.support.converter.MessageConversionException;

import java.io.IOException;

public class ObjectMessageConverter extends AbstractJsonMessageConverter {

    private static final Logger logger = LoggerFactory.getLogger(ObjectMessageConverter.class);

    private ObjectMapper jsonObjectMapper = new ObjectMapper();

    private Jackson2JavaTypeMapper jackson2JavaTypeMapper = new DefaultJackson2JavaTypeMapper();

    public Jackson2JavaTypeMapper getJackson2JavaTypeMapper() {
        return jackson2JavaTypeMapper;
    }

    @Override
    protected Message createMessage(Object o, MessageProperties messageProperties) throws MessageConversionException {
        byte[] bytes = null;
        try {
            String jsonString = jsonObjectMapper.writeValueAsString(o);
            bytes = jsonString.getBytes(getDefaultCharset());
        } catch (IOException e) {
            throw new MessageConversionException("Failed to convert Message content", e);
        }
        messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
        messageProperties.setContentEncoding(getDefaultCharset());
        if (bytes != null) {
            messageProperties.setContentLength(bytes.length);
        }
        if (getClassMapper() == null) {
            getJackson2JavaTypeMapper().fromJavaType(jsonObjectMapper.constructType(o.getClass()), messageProperties);
        } else {
            getClassMapper().fromClass(o.getClass(), messageProperties);
        }
        return new Message(bytes, messageProperties);
    }

    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        Object content = null;
        MessageProperties properties = message.getMessageProperties();
        if (properties != null) {
            String contentType = properties.getContentType();
            Object body = message.getBody();
            if (body instanceof byte[]) {
                content = new String((byte[]) body);
            }
            logger.warn("Could not convert incoming message with content-type [" + contentType + "]");
        }
        if (content == null) {
            content = message.getBody();
        }
        return content;
    }
}
